package
{
	import flash.utils.ByteArray;
	
	public class PDB
	{
		private var PDBPath:String;
		private var PDBContents:ByteArray = new ByteArray();
		private var PDBLines:Array;
		public var PDBData:Array = new Array();
		
		public function PDB(Path:String) {
			Flow.Ord(function():void {
				PDBPath = Path;
				Loader.Load(Path);
			});

			Flow.Ord(function():void {
				PDBContents.writeBytes(Loader.buffer);
				np.debug.print("PDB: Loaded: " + PDBPath + " length: " + PDBContents.length + " bytes.");
				
				PDBLines = PDBContents.toString().split("\n");
				
				np.debug.print("lines: " + PDBLines.length + ".");
				np.debug.print("l1=" + PDBLines[800] + ".");
				
				//np.debug.print("S=" + (PDBLines[800] as String).substring(22,26));
				
				/*
				np.debug.print("S=" + (PDBLines[1] as String).substring(0,6));
				
				np.debug.print("closure test:");
				var l:uint;
								
				var cls:Function = function(x:uint, y:uint):String {
					return (PDBLines[l] as String).substring(x,y);
				};
				*/
				
				//var tst:Function = function(s:String):String{return s.substring(11,50)};
				/*
				l = 1;
				np.debug.print("cS=" + cls(0,6));
				l = 2;
				np.debug.print("cS=" + cls(0,6));
				np.debug.print("cS=" + cls(39,46));
				np.debug.print("pcS=" + (parseFloat(cls(39,46)) + 1.11) );
				*/
				
				/*
				var finder:Function = function(x:uint, y:uint):Function {
					return function(s:String):String {
						return s.substring(x,y);
					}
				};

				var tst:Function = finder(0,6);
				np.debug.print("X=" + tst(PDBLines[2]));
				*/
				
				Parse();
				
				Flow.Next();
			});
		}
		
		private function sub(s:String, a:uint, b:uint):String {
			return s.substring(a-1,b);
		}
		
		/* This should eventually detect errors. */
		private function Parse():void {
			var chain:uint = 0;
			
			function pdbStr(a:uint, b:uint):Function {
				return function():String {
					return sub(s,a,b);
				}
			}
			
			function pdbInt(a:uint, b:uint):Function {
				return function():int {
					return parseInt(sub(s,a,b));
				}
			}
			
			function pdbFloat(a:uint, b:uint):Function {
				return function():Number {
					return parseFloat(sub(s,a,b));
				}
			}

			function mkatom():void {
			}
			
			np.debug.print("TEST!");
			
			const Rules:Object = {"HEADER":{classification:pdbStr(11,50), depDate:pdbStr(51,59), idCode:pdbStr(63,66)},
								  "TITLE ":{continuation:pdbStr(9,10), title:pdbStr(11,80)},
								  "ATOM  ":{action:mkatom,
								  			serial:pdbInt(7,11), name:pdbStr(13,16), altLoc:pdbStr(17,17), resName:pdbStr(18,20),
								  			chainID:pdbStr(22,22), resSeq:pdbInt(23,26), iCode:pdbStr(27,27), 
								  			x:pdbFloat(31,38), y:pdbFloat(39,46), z:pdbFloat(47,54),
								  			occupancy:pdbFloat(55,60), tempFactor:pdbFloat(61,66), element:pdbStr(77,78), charge:pdbStr(79,80)}
								 };

			for each (var s:String in PDBLines) {
				var i:Object = Rules[sub(s,1,6)];
				if (sub(s,1,6) == "ATOM  " && i.serial() < 50) np.debug.print("ITEM="+i.resName());
			}
			
			//Rules["HEADER"].a();			
			//np.debug.print("X="+Rules["HEADER"].a.call());
			
			np.debug.print("pdb done!");
			
		}
		
		/* Dump PDB info. */
		public function Dump():void {
			
		}
	}
}